const cron = require('node-cron');
const { config } = require('../config/config');
const logger = require('./logger');

class SchedulerManager {
  constructor() {
    this.tasks = new Map();
    this.isEnabled = config.scheduler.enableScheduledTasks;
    
    // 设置时区
    process.env.TZ = config.scheduler.timezone;
  }

  // 添加定时任务
  addTask(name, schedule, task, options = {}) {
    if (!this.isEnabled) {
      logger.warn(`任务调度已禁用，跳过任务: ${name}`);
      return false;
    }

    try {
      // 验证cron表达式
      if (!cron.validate(schedule)) {
        throw new Error(`无效的cron表达式: ${schedule}`);
      }

      // 创建任务
      const job = cron.schedule(schedule, async () => {
        try {
          logger.info(`开始执行定时任务: ${name}`);
          const startTime = Date.now();
          
          await task();
          
          const duration = Date.now() - startTime;
          logger.info(`定时任务执行完成: ${name}, 耗时: ${duration}ms`);
        } catch (error) {
          logger.error(`定时任务执行失败: ${name}`, error);
        }
      }, {
        scheduled: false, // 默认不立即启动
        timezone: config.scheduler.timezone,
        ...options
      });

      // 存储任务信息
      this.tasks.set(name, {
        job,
        schedule,
        task,
        options,
        isRunning: false,
        lastRun: null,
        nextRun: null,
        runCount: 0,
        errorCount: 0
      });

      logger.info(`定时任务已添加: ${name}, 调度: ${schedule}`);
      return true;
    } catch (error) {
      logger.error(`添加定时任务失败: ${name}`, error);
      return false;
    }
  }

  // 启动任务
  startTask(name) {
    const taskInfo = this.tasks.get(name);
    if (!taskInfo) {
      logger.warn(`任务不存在: ${name}`);
      return false;
    }

    if (taskInfo.isRunning) {
      logger.warn(`任务已在运行: ${name}`);
      return false;
    }

    try {
      taskInfo.job.start();
      taskInfo.isRunning = true;
      taskInfo.nextRun = taskInfo.job.nextDate().toDate();
      
      logger.info(`定时任务已启动: ${name}`);
      return true;
    } catch (error) {
      logger.error(`启动定时任务失败: ${name}`, error);
      return false;
    }
  }

  // 停止任务
  stopTask(name) {
    const taskInfo = this.tasks.get(name);
    if (!taskInfo) {
      logger.warn(`任务不存在: ${name}`);
      return false;
    }

    if (!taskInfo.isRunning) {
      logger.warn(`任务未在运行: ${name}`);
      return false;
    }

    try {
      taskInfo.job.stop();
      taskInfo.isRunning = false;
      taskInfo.nextRun = null;
      
      logger.info(`定时任务已停止: ${name}`);
      return true;
    } catch (error) {
      logger.error(`停止定时任务失败: ${name}`, error);
      return false;
    }
  }

  // 删除任务
  removeTask(name) {
    const taskInfo = this.tasks.get(name);
    if (!taskInfo) {
      logger.warn(`任务不存在: ${name}`);
      return false;
    }

    try {
      if (taskInfo.isRunning) {
        taskInfo.job.stop();
      }
      taskInfo.job.destroy();
      this.tasks.delete(name);
      
      logger.info(`定时任务已删除: ${name}`);
      return true;
    } catch (error) {
      logger.error(`删除定时任务失败: ${name}`, error);
      return false;
    }
  }

  // 立即执行任务
  async runTask(name) {
    const taskInfo = this.tasks.get(name);
    if (!taskInfo) {
      logger.warn(`任务不存在: ${name}`);
      return false;
    }

    try {
      logger.info(`手动执行定时任务: ${name}`);
      const startTime = Date.now();
      
      await taskInfo.task();
      
      const duration = Date.now() - startTime;
      taskInfo.lastRun = new Date();
      taskInfo.runCount++;
      
      logger.info(`手动执行定时任务完成: ${name}, 耗时: ${duration}ms`);
      return true;
    } catch (error) {
      taskInfo.errorCount++;
      logger.error(`手动执行定时任务失败: ${name}`, error);
      return false;
    }
  }

  // 获取任务信息
  getTaskInfo(name) {
    const taskInfo = this.tasks.get(name);
    if (!taskInfo) {
      return null;
    }

    return {
      name,
      schedule: taskInfo.schedule,
      isRunning: taskInfo.isRunning,
      lastRun: taskInfo.lastRun,
      nextRun: taskInfo.isRunning ? taskInfo.job.nextDate().toDate() : null,
      runCount: taskInfo.runCount,
      errorCount: taskInfo.errorCount
    };
  }

  // 获取所有任务信息
  getAllTasks() {
    const tasks = [];
    for (const [name, taskInfo] of this.tasks) {
      tasks.push({
        name,
        schedule: taskInfo.schedule,
        isRunning: taskInfo.isRunning,
        lastRun: taskInfo.lastRun,
        nextRun: taskInfo.isRunning ? taskInfo.job.nextDate().toDate() : null,
        runCount: taskInfo.runCount,
        errorCount: taskInfo.errorCount
      });
    }
    return tasks;
  }

  // 启动所有任务
  startAllTasks() {
    if (!this.isEnabled) {
      logger.warn('任务调度已禁用，无法启动任务');
      return false;
    }

    let startedCount = 0;
    for (const [name] of this.tasks) {
      if (this.startTask(name)) {
        startedCount++;
      }
    }

    logger.info(`已启动 ${startedCount} 个定时任务`);
    return startedCount;
  }

  // 停止所有任务
  stopAllTasks() {
    let stoppedCount = 0;
    for (const [name] of this.tasks) {
      if (this.stopTask(name)) {
        stoppedCount++;
      }
    }

    logger.info(`已停止 ${stoppedCount} 个定时任务`);
    return stoppedCount;
  }

  // 获取调度器状态
  getStatus() {
    const totalTasks = this.tasks.size;
    const runningTasks = Array.from(this.tasks.values()).filter(task => task.isRunning).length;
    
    return {
      enabled: this.isEnabled,
      totalTasks,
      runningTasks,
      stoppedTasks: totalTasks - runningTasks,
      timezone: config.scheduler.timezone
    };
  }

  // 预定义任务模板
  static getTaskTemplates() {
    return {
      // 每分钟执行
      everyMinute: '* * * * *',
      
      // 每5分钟执行
      everyFiveMinutes: '*/5 * * * *',
      
      // 每10分钟执行
      everyTenMinutes: '*/10 * * * *',
      
      // 每30分钟执行
      everyThirtyMinutes: '*/30 * * * *',
      
      // 每小时执行
      everyHour: '0 * * * *',
      
      // 每天凌晨2点执行
      dailyAt2AM: '0 2 * * *',
      
      // 每天凌晨3点执行
      dailyAt3AM: '0 3 * * *',
      
      // 每周一凌晨2点执行
      weeklyMonday: '0 2 * * 1',
      
      // 每月1号凌晨2点执行
      monthlyFirst: '0 2 1 * *',
      
      // 工作日每小时执行
      weekdaysHourly: '0 * * * 1-5',
      
      // 周末每小时执行
      weekendsHourly: '0 * * * 6,0'
    };
  }

  // 创建数据清理任务
  createCleanupTask() {
    return this.addTask(
      'data-cleanup',
      '0 2 * * *', // 每天凌晨2点
      async () => {
        logger.info('开始执行数据清理任务');
        
        // 清理过期日志
        // 清理临时文件
        // 清理过期缓存
        // 清理过期会话
        
        logger.info('数据清理任务完成');
      },
      {
        scheduled: true
      }
    );
  }

  // 创建健康检查任务
  createHealthCheckTask() {
    return this.addTask(
      'health-check',
      '*/5 * * * *', // 每5分钟
      async () => {
        logger.debug('执行健康检查');
        
        // 检查数据库连接
        // 检查Redis连接
        // 检查外部API连接
        // 检查系统资源使用情况
        
        logger.debug('健康检查完成');
      },
      {
        scheduled: true
      }
    );
  }

  // 创建备份任务
  createBackupTask() {
    return this.addTask(
      'data-backup',
      '0 3 * * *', // 每天凌晨3点
      async () => {
        logger.info('开始执行数据备份任务');
        
        // 备份数据库
        // 备份配置文件
        // 备份日志文件
        
        logger.info('数据备份任务完成');
      },
      {
        scheduled: true
      }
    );
  }
}

// 创建全局调度器实例
const schedulerManager = new SchedulerManager();

module.exports = {
  SchedulerManager,
  schedulerManager
}; 